package planner;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import parser.*;
import represent.*;
import represent.expression.Expression;
import represent.type.Type;
import server.SimpleDB;
import storage.transaction.Transaction;


/**
 * The basic planner for SQL update statements.
 * @author sciore
 */
public class BasicUpdatePlanner implements UpdatePlanner {

	public int executeDelete(DeleteData data, Transaction tx) {
		Plan p = new TablePlan(data.tableName(), tx);
		p = new SelectPlan(p, data.pred());
		UpdateScan us = (UpdateScan) p.open(null);
		int count = 0;
		while(us.next()) {
			us.delete();
			count++;
		}
		us.close();
		return count;
	}

	public int executeModify(ModifyData data, Transaction tx) {
		Plan p = new TablePlan(data.tableName(), tx);
		p = new SelectPlan(p, data.pred());
		UpdateScan us = (UpdateScan) p.open(null);
		int count = 0;
		while(us.next()) {
			Iterator<String> i = data.targetField().iterator();
			Iterator<Expression> j = data.newValue().iterator();
			while( i.hasNext() ) {
				String field = i.next();
				Expression newVal = j.next();
				Type val = newVal.evaluate(us);
				us.setVal(field, val);
			}
			count++;
		}
		us.close();
		return count;
	}

	public int executeInsert(InsertData data, Transaction tx) {
		Plan p = new TablePlan(data.tableName(), tx);
		UpdateScan us = (UpdateScan) p.open(null);
		us.insert();
		Iterator<Type> iter = data.vals().iterator();
		Collection<String> flds = null;
	      if(data.fields() == null)
	    	  flds = SimpleDB.mdMgr().getTableInfo(data.tableName(), tx).getFields();
	      else
	    	  flds = data.fields();
	      for (String fldname : flds) {
	         Type val = iter.next();
	         us.setVal(fldname, val);
	      }
		us.close();
		return 1;
	}

	public int executeCreateTable(CreateTableData data, Transaction tx) {
		SimpleDB.mdMgr().createTable(data.tableName(), data.newSchema(), tx);
		return 0;
	}

	public int executeCreateIndex(CreateIndexData data, Transaction tx) {
		SimpleDB.mdMgr().createIndex(data.indexName(), data.tableName(), data.fieldName(), tx);
		return 0;  
	}

	public int executeCreateDB(CreateDBData data, Transaction tx) {
		SimpleDB.mdMgr().createDB(data.dbName(), tx);
		return 0;
	}

	public int executeDropDB(DropDBData data, Transaction tx) {
		SimpleDB.mdMgr().dropDB(data.dbName(), tx);
		return 0;
	}

	public int executeDropIndex(DropIndexData data, Transaction tx) {
		SimpleDB.mdMgr().dropIndex(data.tableName(), data.indexName(), tx);
		return 0;
	}

	public int executeDropTable(DropTableData data, Transaction tx) {
		List<String> names = data.tableName();
		for (String n : names)
			SimpleDB.mdMgr().dropTable(n, tx);
		return 0;
	}

	public int executeUseDB(UseDBData data, Transaction tx) {
		SimpleDB.mdMgr().useDB(data.dbName(), tx);
		return 0;
	}
}
